﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace JMacia.Gaming.d20.Core.Traits
{
    public class Attack : Trait, ID20Modifier
    {
        #region Private Fields
        private bool _autoSucceed = true;
        private bool _autoFail = true;
        private Ability _keyAbility;
        private int _flurryAttacks = 0;
        private bool _isNaturalAttack = false;
        private Damage _damage;
        #endregion

        #region Public Static Readonly Fields
        public static readonly ModifierType[] StandardAllowedBonusTypes = new ModifierType[]{
            SystemModifierType.Ability,
            SystemModifierType.Circumstance,
            SystemModifierType.Competence,
            SystemModifierType.Enhancement,
            SystemModifierType.Insight,
            SystemModifierType.Luck,
            SystemModifierType.Morale,
            SystemModifierType.Profane,
            SystemModifierType.Racial,
            SystemModifierType.Sacred,
            SystemModifierType.Size,
            SystemModifierType.Untyped};
        #endregion

        #region Constructors

        public Attack(string name, int baseAttack, Ability keyAbility)
            : this(name, baseAttack, keyAbility, null, new Modifiers(), StandardAllowedBonusTypes)
        { }

        public Attack(string name, int baseAttack, Ability keyAbility, Damage damage)
            : this(name, baseAttack, keyAbility, damage, new Modifiers(), StandardAllowedBonusTypes)
        { }

        public Attack(string name, int baseAttack, Ability keyAbility, Modifiers modifiers)
            : this(name, baseAttack, keyAbility, null, modifiers, StandardAllowedBonusTypes)
        { }

        public Attack(string name, int baseAttack, Ability keyAbility, Damage damage, Modifiers modifiers)
            : this(name, baseAttack, keyAbility, damage, modifiers, StandardAllowedBonusTypes)
        { }

        public Attack(string name, int baseAttack, Ability keyAbility, Damage damage,
            Modifiers modifiers, ModifierType[] allowedBonusTypes)
            : base(name, baseAttack, modifiers, allowedBonusTypes)
        {
            KeyAbility = keyAbility;
            _damage = damage;
        }

        #endregion

        #region Public Properties

        public Ability KeyAbility
        {
            get { return _keyAbility; }
            set
            {
                if (_keyAbility != null)
                {
                    Modifiers.Remove(_keyAbility.Modifier);
                }
                _keyAbility = value;
                if (_keyAbility != null)
                {
                    Modifiers.Add(_keyAbility.Modifier);
                }
            }
        }

        public Damage Damage
        {
            get { return _damage; }
            set { _damage = value; }
        }

        /// <summary>
        /// The standard full attack pattern for this attack type
        /// </summary>
        public int[] TotalFullAttack
        {
            get
            {
                int baseAttack = Base;
                int totalAttack = Total;
                List<int> attacks = new List<int>();
                for (int i = 0; i < _flurryAttacks; i++)
                {
                    attacks.Add(totalAttack);
                }
                do
                {
                    attacks.Add(totalAttack);
                    totalAttack -= 5;
                    baseAttack -= 5;
                } while (attacks.Count < 4 + _flurryAttacks && baseAttack > 0 && !_isNaturalAttack);
                return attacks.ToArray();
            }
        }

        public int FlurryAttacks
        {
            get { return _flurryAttacks; }
            set { _flurryAttacks = value; }
        }

        public bool IsNaturalAttack
        {
            get { return _isNaturalAttack; }
            set { _isNaturalAttack = value; }
        }
        #endregion

        #region ID20Modifier Members

        public bool AutoSucceed
        {
            get
            {
                return _autoSucceed;
            }
            set
            {
                _autoSucceed = value;
            }
        }

        public bool AutoFail
        {
            get
            {
                return _autoFail;
            }
            set
            {
                _autoFail = value;
            }
        }

        #endregion
    }
}
